package com.tanhua.server.service;

import com.alibaba.dubbo.config.annotation.Reference;
import com.tanhua.dubbo.server.api.SoundApi;
import com.tanhua.dubbo.server.pojo.Sound;
import com.tanhua.server.pojo.User;
import com.tanhua.server.pojo.UserInfo;
import com.tanhua.server.utils.UserThreadLocal;
import com.tanhua.server.vo.SoundUploadResult;
import com.tanhua.server.vo.SoundVo;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.util.List;
import java.util.Random;

/**
 * @author zwy
 */
@Service
public class SoundService {

    @Autowired
    private SoundUploadService soundUploadService;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Reference(version = "1.0.0")
    private SoundApi soundApi;

    @Autowired
    private UserInfoService userInfoService;

    /**
     * 功能描述: saveSound   保存声音
     *
     * @param soundFile
     * @Return: {@link String}
     * @throws:
     * @Author: zwy
     * @Date: 2020/12/22 22:00
     */
    public String saveSound(MultipartFile[] soundFile) {
        User user = UserThreadLocal.get();
        Sound sound = new Sound();
        sound.setUserId(user.getId());

        //上传声音
        for (MultipartFile file : soundFile) {
            //调用声音上传工具类上传声音
            SoundUploadResult soundUploadResult = this.soundUploadService.upload(file);
            //获取上传的路径
            String soundUrl = soundUploadResult.getName();
            //将路径保存到sound对象中
            sound.setSoundUrl(soundUrl);
        }
        return this.soundApi.saveSound(sound);
    }

    /**
     * 功能描述: receiveSound   接收声音
     *
     * @param
     * @Return: {@link SoundVo}
     * @throws:
     * @Author: zwy
     * @Date: 2020/12/26 2:51
     */
    public SoundVo receiveSound() {
        User user = UserThreadLocal.get();

        //创建sound虚拟实体类
        SoundVo soundVo = new SoundVo();
        //创建存入redis中的key
        String getKey = "SOUND_GET_" + user.getId();
        //获取值
        String count = this.redisTemplate.opsForValue().get(getKey);
        //判断count如果为空,则赋给其默认值
        if (StringUtils.isEmpty(count)) {
            this.redisTemplate.opsForValue().set(getKey, String.valueOf(10));
            count = "10";
        }
        //将count转为integer类型
        Integer integer = Integer.valueOf(count);
        //判断integer是否大于零
        if (integer > 0) {
            Long userId = user.getId();
            //则调用接收方法
            List<Sound> sounds = this.soundApi.receiveSound(userId);
            //如果集合为空,则说明数据库中的声音已经被听完
            if (CollectionUtils.isEmpty(sounds)) {
                return null;
            }
            //查到一条排除自己声音之后的声音
            Sound sound = this.distinct(sounds);
            //给声音赋值
            soundVo.setUserId((sound.getUserId()));
            UserInfo userInfo = this.userInfoService.queryUserInfoById(sound.getUserId());
            soundVo.setAvatar(userInfo.getLogo());
            soundVo.setNickname(userInfo.getNickName());
            soundVo.setGender(userInfo.getSex());
            soundVo.setAge(userInfo.getAge());
            soundVo.setSoundUrl(sound.getSoundUrl());
            //让其接收语音的次数减少
            integer--;
            //获取指定key的值进行减1
            this.redisTemplate.opsForValue().decrement(getKey);
            //将自减过的次数存入对象
            soundVo.setRemainingTimes(integer);
            return soundVo;
        }
        //如果次数为零,则返回null
        return null;
    }

    /**
     * 去重  排除自己的声音
     *
     * @param sounds
     * @return
     */
    private Sound distinct(List<Sound> sounds) {
        //新建一个随机数
        Random random = new Random();
        int index = random.nextInt(sounds.size() - 1);
        if (index <= 0) {
            index = 0;
        }
        Sound sound = sounds.get(index);
        //将听过的语音全部存在redis中
        String gotKey = "SOUND_GOT_" + sound.getId();
        //获取值
        String count = this.redisTemplate.opsForValue().get(gotKey);
        //如果不为null,继续调用此方法,直至查出来的数据他没有听过
        if (count != null) {
            this.distinct(sounds);
        }
        //然后将其在redis中的值赋值为永久生效
        this.redisTemplate.opsForValue().set(gotKey, "1");
        //返回取出的数据
        return sound;
    }
}
